﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EnterpriseWebsiteUtil.Helper
{
    public class Mapper
    {
        /// <summary>
        /// 映射List
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="source"></param>
        /// <returns></returns>
        public List<T> MapList<T>(object source)
        {
            // 获取 T 类型和 T2 类型
            var tType = typeof(T);
            var t2Type = source.GetType().GetGenericArguments().Single();
            // 获取 T 类型的属性
            var tProperties = tType.GetProperties();
            // 创建返回的 List<T>
            var resultList = new List<T>();
            // 遍历 source 中的每个元素
            foreach (var sourceItem in (IEnumerable)source)
            {
                // 创建 T 的实例
                var resultItem = (T)Activator.CreateInstance(tType);
                // 遍历 T 类型的属性
                foreach (var tProperty in tProperties)
                {
                    // 获取 T2 类型对应的属性
                    var t2Property = t2Type.GetProperty(tProperty.Name);

                    // 如果 T2 类型中存在对应的属性，则将其值赋给 T 类型的属性
                    if (t2Property != null)
                    {
                        // 判断属性类型是否为枚举类型
                        if (tProperty.PropertyType.IsEnum)
                        {
                            // 如果是枚举类型，则需要将源属性的值转换为相应的枚举值
                            var enumValue = Enum.Parse(tProperty.PropertyType, t2Property.GetValue(sourceItem).ToString());
                            tProperty.SetValue(resultItem, enumValue);
                        }
                        else
                        {
                            // 如果不是枚举类型，则直接赋值
                            var value = t2Property.GetValue(sourceItem);
                            tProperty.SetValue(resultItem, value);
                        }
                    }
                }
                // 将转换后的 T 类型的实例加入返回的 List<T> 中
                resultList.Add(resultItem);
            }
            return resultList;
        }

        public T Map<T>(object source)
        {
            // 创建目标对象
            var destination = Activator.CreateInstance<T>();

            // 遍历源对象的属性并赋值给目标对象
            foreach (var sourceProperty in source.GetType().GetProperties())
            {
                var destinationProperty = typeof(T).GetProperty(sourceProperty.Name);
                if (destinationProperty != null && destinationProperty.CanWrite)
                {
                    destinationProperty.SetValue(destination, sourceProperty.GetValue(source));
                }
                else // 如果属性不存在或不可写，检查是否为枚举类型
                {
                    var sourceField = source.GetType().GetField(sourceProperty.Name);
                    var destinationField = typeof(T).GetField(sourceProperty.Name);
                    if (sourceField != null && destinationField != null && destinationField.FieldType.IsEnum)
                    {
                        var sourceValue = sourceField.GetValue(source);
                        destinationField.SetValue(destination, Enum.Parse(destinationField.FieldType, sourceValue.ToString()));
                    }
                }
            }

            return destination;
        }

        public T Map<T>(object source,T target)
        {

            // 遍历源对象的属性并赋值给目标对象
            foreach (var sourceProperty in source.GetType().GetProperties())
            {
                var destinationProperty = typeof(T).GetProperty(sourceProperty.Name);
                if (destinationProperty != null && destinationProperty.CanWrite)
                {
                    destinationProperty.SetValue(target, sourceProperty.GetValue(source));
                }
                else // 如果属性不存在或不可写，检查是否为枚举类型
                {
                    var sourceField = source.GetType().GetField(sourceProperty.Name);
                    var destinationField = typeof(T).GetField(sourceProperty.Name);
                    if (sourceField != null && destinationField != null && destinationField.FieldType.IsEnum)
                    {
                        var sourceValue = sourceField.GetValue(source);
                        destinationField.SetValue(target, Enum.Parse(destinationField.FieldType, sourceValue.ToString()));
                    }
                }
            }

            return target;
        }
    }
}
